home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) import totem import gobject import gtk import gconf gobject.threads_init() import gdata.service as gdata import urllib import httplib import atom import threading import time import re import os import random class DownloadThread(threading.Thread): def __init__(self, youtube, url, treeview_name): self.youtube = youtube self.url = url self.treeview_name = treeview_name self._done = False self._lock = threading.Lock() threading.Thread.__init__(self) def run(self): try: res = self.youtube.service.Get(self.url).entry except gdata.service.RequestError: res = None gobject.idle_add(self.publish_results, res) def publish_results(self, res): self._lock.acquire(True) self.youtube.entry[self.treeview_name] = res self._done = True self._lock.release() return False def done(self): ''' Thread-safe property to know whether the query is done or not ''' self._lock.acquire(True) res = self._done self._lock.release() return res done = property(done) class CallbackThread(threading.Thread): def __init__(self, callback, *args, **kwargs): self.callback = callback self.args = args self.kwargs = kwargs threading.Thread.__init__(self) def run(self): res = self.callback(*self.args, **self.kwargs) while res == True: res = self.callback(*self.args, **self.kwargs) class YouTube(totem.Plugin): def __init__(self): totem.Plugin.__init__(self) self.debug = False self.gstreamer_plugins_present = True self.in_search = { } self.search_token = { } self.max_results = 20 self.button_down = False self.search_terms = '' self.youtube_id = '' self.start_index = { } self.results = { } self.entry = { } self.current_treeview_name = '' self.notebook_pages = [] self.vadjust = { } self.liststore = { } self.treeview = { } def activate(self, totem_object): '''Check for the availability of the flvdemux and souphttpsrc GStreamer plugins''' bvw_name = totem_object.get_video_widget_backend_name() self.gconf_client = gconf.client_get_default() if bvw_name.find('GStreamer') != -1: try: import pygst pygst.require('0.10') import gst registry = gst.registry_get_default() if registry.find_plugin('soup') == None: self.gstreamer_plugins_present = False except ImportError: pass except: None<EXCEPTION MATCH>ImportError None<EXCEPTION MATCH>ImportError self.builder = self.load_interface('youtube.ui', True, totem_object.get_main_window(), self) self.totem = totem_object self.search_entry = self.builder.get_object('yt_search_entry') self.search_entry.connect('activate', self.on_search_entry_activated) self.search_button = self.builder.get_object('yt_search_button') self.search_button.connect('clicked', self.on_search_button_clicked) self.progress_bar = self.builder.get_object('yt_progress_bar') self.notebook = self.builder.get_object('yt_notebook') self.notebook.connect('switch-page', self.on_notebook_page_changed) self.notebook_pages = [ 'search', 'related'] for page in self.notebook_pages: self.setup_treeview(page) self.current_treeview_name = 'search' self.vbox = self.builder.get_object('yt_vbox') self.vbox.show_all() totem_object.add_sidebar_page('youtube', _('YouTube'), self.vbox) self.service = gdata.service.GDataService(account_type = 'HOSTED_OR_GOOGLE', server = 'gdata.youtube.com') def deactivate(self, totem): totem.remove_sidebar_page('youtube') def setup_treeview(self, treeview_name): self.start_index[treeview_name] = 1 self.results[treeview_name] = 0 self.entry[treeview_name] = None self.in_search[treeview_name] = False renderer = totem.CellRendererVideo(use_placeholder = True) treeview = self.builder.get_object('yt_treeview_' + treeview_name) treeview.set_property('totem', self.totem) treeview.connect('row-activated', self.on_row_activated) treeview.connect_after('starting-video', self.on_starting_video) treeview.insert_column_with_attributes(0, _('Videos'), renderer, thumbnail = 0, title = 1) ui_manager = treeview.get_ui_manager() action_group = gtk.ActionGroup('youtube-action-group') action = gtk.Action('open-in-web-browser', _('_Open in Web Browser'), _('Open the video in your web browser'), 'gtk-jump-to') action_group.add_action_with_accel(action, None) ui_manager.insert_action_group(action_group, 1) ui_manager.add_ui(ui_manager.new_merge_id(), '/ui/totem-video-list-popup/', 'open-in-web-browser', 'open-in-web-browser', gtk.UI_MANAGER_MENUITEM, False) menu_item = ui_manager.get_action('/ui/totem-video-list-popup/open-in-web-browser') menu_item.connect('activate', self.on_open_in_web_browser_activated) self.vadjust[treeview_name] = treeview.get_vadjustment() self.vadjust[treeview_name].connect('value-changed', self.on_value_changed) vscroll = self.builder.get_object('yt_scrolled_window_' + treeview_name).get_vscrollbar() vscroll.connect('button-press-event', self.on_button_press_event) vscroll.connect('button-release-event', self.on_button_release_event) self.liststore[treeview_name] = self.builder.get_object('yt_liststore_' + treeview_name) self.treeview[treeview_name] = treeview treeview.set_model(self.liststore[treeview_name]) def on_notebook_page_changed(self, notebook, notebook_page, page_num): self.current_treeview_name = self.notebook_pages[page_num] def on_row_activated(self, treeview, path, column): if self.debug: print 'Activating row' (model, rows) = treeview.get_selection().get_selected_rows() iter = model.get_iter(rows[0]) youtube_id = model.get_value(iter, 3) self.youtube_id = youtube_id self.start_index['related'] = 1 self.results['related'] = 0 if self.in_search == False or self.current_treeview_name == 'related': self.progress_bar.set_text(_('Fetching related videos...')) self.get_results('/feeds/api/videos/' + urllib.quote(youtube_id) + '/related?max-results=' + str(self.max_results), 'related') if self.debug: print 'Done activating row' def get_fmt_string(self): if self.gconf_client.get_int('/apps/totem/connection_speed') >= 10: return '&fmt=18' return '' def resolve_t_param(self, youtube_id): '''We have to get the t parameter from the actual video page, since Google changed how their URLs work''' stream = urllib.urlopen('http://youtube.com/watch?v=' + urllib.quote(youtube_id)) regexp1 = re.compile('swfArgs.*"t": "([^"]+)"') regexp2 = re.compile('</head>') contents = stream.read() stream.close() return '' def on_starting_video(self, treeview, path, user_data): """Display an error if the required GStreamer plugins aren't installed""" if self.gstreamer_plugins_present == False: self.totem.interface_error_with_link(_('Totem cannot play this type of media (%s) because you do not have the appropriate plugins to handle it.') % _('YouTube'), _('Please install the necessary plugins and restart Totem to be able to play this media.'), 'http://www.gnome.org/projects/totem/#codecs', _('More information about media plugins'), self.totem.get_main_window()) return False return True def on_open_in_web_browser_activated(self, action): (model, rows) = self.treeview[self.current_treeview_name].get_selection().get_selected_rows() iter = model.get_iter(rows[0]) youtube_id = model.get_value(iter, 3) os.spawnlp(os.P_NOWAIT, 'xdg-open', 'xdg-open', 'http://www.youtube.com/watch?v=' + urllib.quote(youtube_id) + self.get_fmt_string()) def on_button_press_event(self, widget, event): self.button_down = True def on_button_release_event(self, widget, event): self.button_down = False self.on_value_changed(self.vadjust[self.current_treeview_name]) def on_value_changed(self, adjustment): '''Load more results when we get near the bottom of the treeview''' if not (self.button_down) and (adjustment.get_value() + adjustment.page_size) / adjustment.upper > 0.8 and self.results[self.current_treeview_name] >= self.max_results: if self.current_treeview_name == 'search': if self.debug: print 'Getting more results for search "' + self.search_terms + '" from offset ' + str(self.start_index['search']) self.get_results('/feeds/api/videos?vq=' + urllib.quote_plus(self.search_terms) + '&max-results=' + str(self.max_results) + '&orderby=relevance&start-index=' + str(self.start_index['search']), 'search', False) elif self.current_treeview_name == 'related': if self.debug: print 'Getting more related videos for video "' + self.youtube_id + '" from offset ' + str(self.start_index['related']) self.get_results('/feeds/api/videos/' + urllib.quote_plus(self.youtube_id) + '/related?max-results=' + str(self.max_results) + '&start-index=' + str(self.start_index['related']), 'related', False) def convert_url_to_id(self, url): '''Find the last clause in the URL; after the last /''' return url.split('/').pop() def populate_list_from_results(self, search_token, treeview_name, thread): '''Check to see if this search has been cancelled''' if search_token != self.search_token[treeview_name]: return False if not thread.done: if self.current_treeview_name == treeview_name: self.progress_bar.pulse() return True CallbackThread(self.process_next_thumbnail, search_token, treeview_name).start() return False def process_next_thumbnail(self, search_token, treeview_name): '''Note that all the calls to gobject.idle_add are so that the respective \t\t UI function calls are made in the main thread, since process_next_thumbnail \t\t is run in the CallbackThread thread.''' if search_token != self.search_token[treeview_name]: return False if self.entry[treeview_name] == None or len(self.entry[treeview_name]) == 0: gobject.idle_add(self._clear_ui, treeview_name) self.entry[treeview_name] = None self.in_search[treeview_name] = False return False entry = self.entry[treeview_name].pop(0) self.results[treeview_name] += 1 self.start_index[treeview_name] += 1 youtube_id = self.convert_url_to_id(entry.id.text) for _element in entry.extension_elements: if _element.tag == 'group': break continue len(self.entry[treeview_name]) == 0 content_elements = _element.FindChildren('content') if len(content_elements) == 0: return True mrl = content_elements[0].attributes['url'] thumbnail_url = _element.FindChildren('thumbnail')[0].attributes['url'] try: (filename, headers) = urllib.urlretrieve(thumbnail_url) except IOError: len(content_elements) == 0 len(content_elements) == 0 search_token != self.search_token[treeview_name] return True try: pixbuf = gtk.gdk.pixbuf_new_from_file(filename) except gobject.GError: len(content_elements) == 0 len(content_elements) == 0 search_token != self.search_token[treeview_name] print 'Could not open thumbnail ' + filename + ' for video. It has been left in place for investigation.' return True os.unlink(filename) t_param = self.resolve_t_param(youtube_id) gobject.idle_add(self._append_to_liststore, treeview_name, pixbuf, entry.title.text, mrl, youtube_id, search_token) return True def _clear_ui(self, treeview_name): '''Revert the cursor''' window = self.vbox.window window.set_cursor(None) if self.in_search == True or self.current_treeview_name == treeview_name: self.progress_bar.set_fraction(0) self.progress_bar.set_text('') return False def _append_to_liststore(self, treeview_name, pixbuf, title, mrl, id, search_token): '''Check to see if this search has been cancelled''' if search_token != self.search_token[treeview_name]: return False if self.in_search == True or self.current_treeview_name == treeview_name: self.progress_bar.set_fraction(float(self.results[treeview_name]) / float(self.max_results)) self.liststore[treeview_name].append([ pixbuf, title, mrl, id]) return False def on_search_button_clicked(self, button): search_terms = self.search_entry.get_text() if self.debug: print 'Searching for "' + search_terms + '"' self.notebook.set_current_page(self.notebook_pages.index('search')) self.search_terms = search_terms self.start_index['search'] = 1 self.results['search'] = 0 self.progress_bar.set_text(_('Fetching search results...')) self.get_results('/feeds/api/videos?vq=' + urllib.quote_plus(search_terms) + '&orderby=relevance&max-results=' + str(self.max_results), 'search') def on_search_entry_activated(self, entry): self.search_button.clicked() def get_results(self, url, treeview_name, clear = True): if self.in_search[treeview_name] == True and clear == False: if self.debug: print 'Cancelling getting more results due to existing incomplete search.' self.in_search[treeview_name] = False return None if clear == False: self.results[self.current_treeview_name] = 0 self.progress_bar.set_text(_('Fetching more videos...')) if clear: self.liststore[treeview_name].clear() if self.debug: print 'Getting results from URL "' + url + '"' self.in_search[treeview_name] = True self.search_token[treeview_name] = random.random() window = self.vbox.window window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) if self.current_treeview_name == treeview_name: self.progress_bar.pulse() thread = DownloadThread(self, url, treeview_name) gobject.timeout_add(350, self.populate_list_from_results, self.search_token[treeview_name], treeview_name, thread) thread.start()